
#include "../type.h"

#include "frame_recive_config.h"
#include "string.h"

typedef struct __FRAME_REC_STRUCT__ FRAME_REC_STRUCT;
struct __FRAME_REC_STRUCT__{
	uint8_t *buffer;
	uint8_t state;
	uint8_t count;	

	uint8_t (*frame_recive_start_check_callback)(uint8_t rec_byte);
	void (*frame_recive_start_check_init_callback)(void);
	void (*frame_recive_get_frame_head_callback)(uint8_t* frame_head, uint8_t* frame_head_len);      //copy the frame head to *frame_head, and return frame_head_len
	
	uint8_t (*frame_recive_finish_check_callback)(uint8_t rec_byte);
	void (*frame_recive_finish_check_init_callback)(void);
	
	uint8_t (*frame_recice_verify_check_callback)(uint8_t* recive_frame, uint8_t recive_frame_len);
	void (*frame_recice_success_callback)(uint8_t* recive_frame, uint8_t recive_frame_len);

	/*
	uint8_t jitter_tick;
	uint8_t long_press_tick;
	uint8_t long_press_repeat_tick;
	uint8_t press_tick_count;
	uint8_t last_state;
	uint8_t (*hal_read_button_state_callbakc)(BUTTON_STRUCT* button);
	void (*press_callback)(BUTTON_STRUCT* button);
	void (*release_callback)(BUTTON_STRUCT* button);
	void (*long_press_callback)(BUTTON_STRUCT* button);
	*/
};


static uint8_t frame_recive_buffer[FRAME_RECIVE_BUFFER_LEN] = {0};
static FRAME_REC_STRUCT frame_recive_s = {0};

void frame_recive_start_check_callback_reg(uint8_t (*frame_recive_start_check_callback)(uint8_t rec_byte))
{
	if(frame_recive_start_check_callback != 0)
		frame_recive_s.frame_recive_start_check_callback = frame_recive_start_check_callback;
}

void frame_recive_start_check_init_callback_reg(void (*frame_recive_start_check_init_callback)(void))
{
	if(frame_recive_start_check_init_callback != 0)
		frame_recive_s.frame_recive_start_check_init_callback = frame_recive_start_check_init_callback;
}

//copy the frame head to *frame_head, and return frame_head_len
void frame_recive_get_frame_head_callback_reg(void (*frame_recive_get_frame_head_callback)(uint8_t* frame_head, uint8_t* frame_head_len))
{
	if(frame_recive_get_frame_head_callback != 0)
		frame_recive_s.frame_recive_get_frame_head_callback = frame_recive_get_frame_head_callback;
}

void frame_recive_finish_check_callback_reg(uint8_t (*frame_recive_finish_check_callback)(uint8_t rec_byte))
{
	if(frame_recive_finish_check_callback != 0)
		frame_recive_s.frame_recive_finish_check_callback = frame_recive_finish_check_callback;
}

void frame_recive_finish_check_init_callback_reg(void (*frame_recive_finish_check_init_callback)(void))
{
	if(frame_recive_finish_check_init_callback != 0)
		frame_recive_s.frame_recive_finish_check_init_callback = frame_recive_finish_check_init_callback;
}

void frame_recice_verify_check_callback_reg(uint8_t (*frame_recice_verify_check_callback)(uint8_t* recive_frame, uint8_t recive_frame_len))
{
	if(frame_recice_verify_check_callback != 0)
		frame_recive_s.frame_recice_verify_check_callback = frame_recice_verify_check_callback;
}

void frame_recice_success_callback_reg(void (*frame_recice_success_callback)(uint8_t* recive_frame, uint8_t recive_frame_len))
{
	if(frame_recice_success_callback != 0)
		frame_recive_s.frame_recice_success_callback = frame_recice_success_callback;
}

void frame_recive_init(void)
{
	frame_recive_s.buffer = frame_recive_buffer;
	frame_recive_s.state = 0;
	frame_recive_s.count = 0;

	if(frame_recive_s.frame_recive_start_check_init_callback != 0)
		frame_recive_s.frame_recive_start_check_init_callback();
	if(frame_recive_s.frame_recive_finish_check_init_callback != 0)
		frame_recive_s.frame_recive_finish_check_init_callback();
	memset(frame_recive_s.buffer, 0, FRAME_RECIVE_BUFFER_LEN);
}

void frame_recive_handler(uint8_t rec_byte)
{
//    printf("rec :%d %x\r\n", rec_byte, rec_byte);
	if(frame_recive_s.state == 0){
		if(frame_recive_s.frame_recive_start_check_callback != 0){
			if(frame_recive_s.frame_recive_start_check_callback(rec_byte) == 1){
				frame_recive_s.state = 1;
				frame_recive_s.frame_recive_get_frame_head_callback(frame_recive_s.buffer, &(frame_recive_s.count));
//				printf("start\r\n");
			}
		}
	}
	else if(frame_recive_s.state == 1){
		frame_recive_buffer[frame_recive_s.count] = rec_byte;
		frame_recive_s.count++;
		if(frame_recive_s.count >= FRAME_RECIVE_BUFFER_LEN){
			frame_recive_s.count = 0;
		}
		if(frame_recive_s.frame_recive_finish_check_callback != 0){
			if(frame_recive_s.frame_recive_finish_check_callback(rec_byte) == 1){
//				printf("finish\r\n");
				if(frame_recive_s.frame_recice_verify_check_callback != 0){
					if(frame_recive_s.frame_recice_verify_check_callback(frame_recive_s.buffer, frame_recive_s.count) == 1){
//						printf("v ok\r\n");
						if(frame_recive_s.frame_recice_success_callback != 0){
							frame_recive_s.frame_recice_success_callback(frame_recive_s.buffer, frame_recive_s.count);
						}
					}
				}
				else{
					if(frame_recive_s.frame_recice_success_callback != 0){
						frame_recive_s.frame_recice_success_callback(frame_recive_s.buffer, frame_recive_s.count);
					}
				}
				frame_recive_init();
			}
		}
	}
	else{
// 		printf("err\r\n");
		frame_recive_init();
	}
}

